
#include "configuration.h"
#include <libconfig.h++>

Configuration *Configuration::_instance = NULL;

Configuration::Configuration() :
	daemon_name("toyhttpd"), _lockfile("/var/lock/subsys/toyhttpd"),
	workers_number(5), _envpath("/usr/bin/env"), _phppath("/usr/bin/php-cgi"),
	_wwwroot("/srv/www"), index_file("index.html"),
	listen_address("127.0.0.1"), listen_port(8080)
{
	allowed_exe.push_back("cgi");
	allowed_exe.push_back("py");
	allowed_exe.push_back("pl");

	readConfig("/etc/toyhttpd.cfg");
	readConfig("toyhttpd.cfg");
}

Configuration::~Configuration() {
	//
}

Configuration &Configuration::instance() {
	if (!_instance) {
		_instance = new Configuration();
	}

	return *_instance;
}

void Configuration::readConfig(std::string path) {
	using namespace libconfig;

	Config cfg;
	try {
		cfg.readFile(path.c_str());
	} catch(const FileIOException &fioex) {
		return; // ignore IO exception
	} catch(const ParseException &pex) {
		fprintf(stderr, "%s: parse error at %d - %s\n", pex.getFile(), pex.getLine(), pex.getError());
		return;
	}

	const Setting &root = cfg.getRoot();
	try {
		const Setting &srv = root["server"];
		std::string dn, lf, addr, ep, www, _if;
		int p;
		if (srv.lookupValue("daemon_name", dn)) {
			daemon_name = dn;
		}
		if (srv.lookupValue("lockfile", lf)) {
			_lockfile = lf;
		}
		if (srv.lookupValue("workers", p)) {
			workers_number = p;
		}
		if (srv.lookupValue("envpath", ep)) {
			_envpath = ep;
		}
		if (srv.lookupValue("phppath", ep)) {
			_phppath = ep;
		}
		if (srv.lookupValue("wwwroot", www)) {
			_wwwroot = www;
		}
		if (srv.lookupValue("indexfile", _if)) {
			index_file = _if;
		}
		const Setting &http = srv["http"];
		if (http.lookupValue("address", addr)) {
			listen_address = addr;
		}
		if (http.lookupValue("port", p)) {
			listen_port = p;
		}
		const Setting &exearr = http["allowedexe"];
		int cnt = exearr.getLength();
		allowed_exe.clear();
		for (int i = 0; i < cnt; i++) {
			const Setting &exeelem = exearr[i];
			allowed_exe.push_back(exeelem);
		}
	} catch (const SettingNotFoundException &nfex) {
		// ignore
	}
}

std::string Configuration::daemonName() const {
	return daemon_name;
}

std::string Configuration::lockfile() const {
	return _lockfile;
}

int Configuration::workersNumber() const {
	return workers_number;
}

std::string Configuration::envpath() const {
	return _envpath;
}

std::string Configuration::phppath() const {
	return _phppath;
}

std::string Configuration::wwwroot() const {
	return _wwwroot;
}

std::string Configuration::indexFile() const {
	return index_file;
}

std::string Configuration::listenAddress() const {
	return listen_address;
}

int Configuration::listenPort() const {
	return listen_port;
}

std::vector<std::string> Configuration::allowedexe() const {
	return allowed_exe;
}
